
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta charset="utf-8"></meta>
      <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
      <title>7.2.&nbsp;Load JSON - Chapter&nbsp;7.&nbsp;Export / Import</title>
      <link rel="stylesheet" type="text/css" href="../../docbook.css"></link>
      <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,400italic,600,300italic"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.css"></link>
      <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/theme/neo.min.css"></link>
      <link rel="stylesheet" type="text/css" href="../../css/chunked-base.css"></link>
      <link rel="stylesheet" type="text/css" href="../../css/extra.css"></link><script src="//code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script><script src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js" type="text/javascript"></script><script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/codemirror.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/addon/runmode/runmode.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.11.0/mode/cypher/cypher.min.js" type="text/javascript"></script><script src="../../javascript/datatable.js" type="text/javascript"></script><script src="../../javascript/colorize.js" type="text/javascript"></script><script src="../../javascript/tabs-for-chunked.js" type="text/javascript"></script><script src="../../javascript/mp-nav.js" type="text/javascript"></script><script src="../../javascript/versionswitcher.js" type="text/javascript"></script><script src="../../javascript/version.js" type="text/javascript"></script><script src="//s3-eu-west-1.amazonaws.com/alpha.neohq.net/docs/new-manual/assets/search.js" type="text/javascript"></script><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"></meta>
      <link rel="prev" href="../" title="Chapter&nbsp;7.&nbsp;Export / Import"></link>
      <link rel="next" href="../load-csv/" title="7.3.&nbsp;Load CSV"></link>
      <link rel="shortcut icon" href="https://neo4j.com/wp-content/themes/neo4jweb/favicon.ico"></link><script>
        $(document).ready(function() {
          CodeMirror.colorize();
          tabTheSource($('body'));
          var $header = $('header').first();
          $header.prepend(
            $('<a href="" id="logo"><img src="https://neo4j.com/wp-content/themes/neo4jweb/assets/images/neo4j-logo-2015.png" alt="Neo4j Logo"></img></a>')
          );
          var $sidebar = $('<div id="sidebar-wrapper"></div>');
          $.get('toc.html', function (d){
            $(d).appendTo($sidebar);
            highlightToc();
            highlightLibraryHeader();
          });
          $sidebar.insertAfter($('header').first());
        });
        </script></head>
   <body>
      <header>
         <div class="searchbox">
            <form id="search-form" class="search" name="search-form" role="search"><input id="search-form-input" name="q" title="search" type="search" lang="en" placeholder="Search Neo4j docs..." aria-label="Search Neo4j documentation" max-length="128" required="required"></input><input id="search-form-button" type="submit" value="Search"></input></form>
         </div>
         <ul class="documentation-library">
            <li><a href="https://neo4j.com/docs/operations-manual/current">Operations Manual</a></li>
            <li><a href="https://neo4j.com/docs/developer-manual/current/">Developer Manual</a></li>
            <li><a href="https://neo4j.com/docs/ogm-manual/current/">OGM Manual</a></li>
            <li><a href="https://neo4j.com/docs/graph-algorithms/current/">Graph Algorithms</a></li>
            <li><a href="https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.4/">APOC</a></li>
            <li><a href="https://neo4j.com/docs/java-reference/current/">Java Reference</a></li>
         </ul>
         <nav id="header-nav"><span class="nav-previous"><a accesskey="p" href="../"><span class="fa fa-long-arrow-left" aria-hidden="true"></span>Export / Import</a></span><span class="nav-current">
               <p class="nav-title hidden">7.2.&nbsp;Load JSON</p></span><span class="nav-next"><a accesskey="n" href="../load-csv/">Load CSV<span class="fa fa-long-arrow-right" aria-hidden="true"></span></a></span></nav>
      </header>
      <div id="search-results" class="hidden"></div>
      <section class="section" id="load-json">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title" style="clear: both"><a class="anchor" href="#load-json"></a>7.2.&nbsp;Load JSON
                  </h2>
               </div>
            </div>
         </div>
         <section class="section" id="_load_json">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_load_json"></a>7.2.1.&nbsp;Load JSON
                     </h3>
                  </div>
               </div>
            </div>
            <p>Web APIs are a huge opportunity to access and integrate data from any sources with your graph.
               Most of them provide the data as JSON.
            </p>
            <p>With <code class="literal">apoc.load.json</code> you can retrieve data from URLs and turn it into map value(s) for Cypher to consume.
               Cypher is pretty good at deconstructing nested documents with dot syntax, slices, <code class="literal">UNWIND</code> etc. so it is easy to turn nested data into graphs.
            </p>
            <p>Sources with multiple JSON objects (JSONL,JSON Lines) in a stream are also supported, like the <a class="link" href="https://dev.twitter.com/streaming/overview/processing" target="_top">streaming Twitter format</a> or the Yelp Kaggle dataset.
            </p>
         </section>
         <section class="section" id="_json_path">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_json_path"></a>7.2.2.&nbsp;Json-Path
                     </h3>
                  </div>
               </div>
            </div>
            <p>Most of the <code class="literal">apoc.load.json</code> and <code class="literal">apoc.convert.*Json</code> procedures and functions now accept a json-path as last argument.
            </p>
            <p>The json-path uses the <a class="link" href="https://github.com/jayway/JsonPath#operators" target="_top">Java implementation by Jayway</a> of <a class="link" href="http://goessner.net/articles/JsonPath/" target="_top">Stefan G&ouml;ssners JSON-Path</a></p>
            <p>Here is some syntax, there are more examples at the links above.</p>
            <p><code class="literal">$.store.book[0].title</code></p>
            <div class="table" id="d0e6062">
               <table class="table" summary="Operators" border="1">
                  <caption class="table-title">Table&nbsp;7.1.&nbsp;Operators</caption>
                  <colgroup>
                     <col class="col_1"></col>
                     <col class="col_2"></col>
                  </colgroup>
                  <thead>
                     <tr>
                        <th style="text-align: left; vertical-align: top; ">Operator</th>
                        <th style="text-align: left; vertical-align: top; ">Description</th>
                     </tr>
                  </thead>
                  <tbody>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">$</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>The root element to query. This starts all path expressions.</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">@</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>The current node being processed by a filter predicate.</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">*</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Wildcard. Available anywhere a name or numeric are required.</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">..</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Deep scan. Available anywhere a name is required.</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">.&lt;name&gt;</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Dot-notated child</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">['&lt;name&gt;' (,'&lt;name&gt;')]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Bracket-notated child or children</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">[&lt;number&gt; (,&lt;number&gt;)]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Array index or indexes</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">[start:end]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Array slice operator</p>
                        </td>
                     </tr>
                     <tr>
                        <td style="text-align: left; vertical-align: top; ">
                           <p><code class="literal">[?(&lt;expression&gt;)]</code></p>
                        </td>
                        <td style="text-align: left; vertical-align: top; ">
                           <p>Filter expression. Expression must evaluate to a boolean value.</p>
                        </td>
                     </tr>
                  </tbody>
               </table>
            </div>
            <p>If used, this path is applied to the json and can be used to extract sub-documents and -values before handing the result to
               Cypher, resulting in shorter statements with complex nested JSON.
            </p>
            <p>There is also a direct <code class="literal">apoc.json.path(json,path)</code> function.
            </p>
            <p>To simplify the JSON URL syntax, you can configure aliases in <code class="literal">conf/neo4j.conf</code>:
            </p><pre class="screen highlight"><code>apoc.json.myJson.url=https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf</code></pre><pre class="screen highlight"><code>CALL apoc.load.json('https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf')

becomes

CALL apoc.load.json('myJson')</code></pre><p>The 3rd value in the <code class="literal">apoc.json.&lt;alias&gt;.url=</code> effectively defines an alias to be used in  <code class="literal">apoc.load.json('&lt;alias&gt;',&#8230;&#8203;.</code></p>
         </section>
         <section class="section" id="_load_json_stackoverflow_example">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_load_json_stackoverflow_example"></a>7.2.3.&nbsp;Load JSON StackOverflow Example
                     </h3>
                  </div>
               </div>
            </div>
            <p>There have been articles before about <a class="link" href="http://neo4j.com/blog/cypher-load-json-from-url/" target="_top">loading JSON from Web-APIs like StackOverflow</a>.
            </p>
            <p>With <code class="literal">apoc.load.json</code> it&#8217;s now very easy to load JSON data from any file or URL.
            </p>
            <p>If the result is a JSON object is returned as a singular map.
               Otherwise if it was an array is turned into a stream of maps.
            </p>
            <p>The URL for retrieving the last questions and answers of the <a class="link" href="http://stackoverflow.com/questions/tagged/neo4j" target="_top">neo4j tag</a> is this:
            </p>
            <p><a class="link" href="https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" target="_top">https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf</a></p>
            <p>Now it can be used from within Cypher directly, let&#8217;s first introspect the data that is returned.</p>
            <p><span class="formalpara-title">JSON data from StackOverflow.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">WITH "https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" AS url
CALL apoc.load.json(url) YIELD value
UNWIND value.items AS item
RETURN item.title, item.owner, item.creation_date, keys(item)</code></pre><p>
               
            </p>
            <div class="informalfigure">
               <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.load.json.so.png" width="800" alt="apoc.load.json.so"></img></div>
            </div>
            <p><span class="formalpara-title">Question authors from StackOverflow using json-path.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">WITH "https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" AS url
CALL apoc.load.json(url,'$.items.owner.name') YIELD value
RETURN name, count(*);</code></pre><p>
               
            </p>
            <p>Combined with the cypher query from the original blog post it&#8217;s easy to create the full Neo4j graph of those entities.
               We filter the original poster last, b/c deleted users have no <code class="literal">user_id</code> anymore.
            </p>
            <p><span class="formalpara-title">Graph data created via loading JSON from StackOverflow.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">WITH "https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" AS url
CALL apoc.load.json(url) YIELD value
UNWIND value.items AS q
MERGE (question:Question {id:q.question_id}) ON CREATE
  SET question.title = q.title, question.share_link = q.share_link, question.favorite_count = q.favorite_count

FOREACH (tagName IN q.tags | MERGE (tag:Tag {name:tagName}) MERGE (question)-[:TAGGED]-&gt;(tag))
FOREACH (a IN q.answers |
   MERGE (question)&lt;-[:ANSWERS]-(answer:Answer {id:a.answer_id})
   MERGE (answerer:User {id:a.owner.user_id}) ON CREATE SET answerer.display_name = a.owner.display_name
   MERGE (answer)&lt;-[:PROVIDED]-(answerer)
)
WITH * WHERE NOT q.owner.user_id IS NULL
MERGE (owner:User {id:q.owner.user_id}) ON CREATE SET owner.display_name = q.owner.display_name
MERGE (owner)-[:ASKED]-&gt;(question)</code></pre><p>
               
            </p>
            <div class="informalfigure">
               <div class="mediaobject"><img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.4/docs/images/apoc.load.json-so-result.png" width="800" alt="apoc.load.json so result"></img></div>
            </div>
         </section>
         <section class="section" id="_load_json_from_twitter_with_additional_parameters">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_load_json_from_twitter_with_additional_parameters"></a>7.2.4.&nbsp;Load JSON from Twitter (with additional parameters)
                     </h3>
                  </div>
               </div>
            </div>
            <p>With <code class="literal">apoc.load.jsonParams</code> you can send additional headers or payload with your JSON GET request, e.g. for the Twitter API:
            </p>
            <p>Configure Bearer and Twitter Search Url token in <code class="literal">neo4j.conf</code></p><pre class="screen highlight"><code>apoc.static.twitter.bearer=XXXX
apoc.static.twitter.url=https://api.twitter.com/1.1/search/tweets.json?count=100&amp;result_type=recent&amp;lang=en&amp;q=</code></pre><p><span class="formalpara-title">Twitter Search via Cypher.&nbsp;</span>
               
            </p><pre class="programlisting highlight"><code data-lang="cypher">CALL apoc.static.getAll("twitter") yield value AS twitter
CALL apoc.load.jsonParams(twitter.url + "oscon+OR+neo4j+OR+%23oscon+OR+%40neo4j",{Authorization:"Bearer "+twitter.bearer},null) yield value
UNWIND value.statuses as status
WITH status, status.user as u, status.entities as e
RETURN status.id, status.text, u.screen_name, [t IN e.hashtags | t.text] as tags, e.symbols, [m IN e.user_mentions | m.screen_name] as mentions, [u IN e.urls | u.expanded_url] as urls</code></pre><p>
               
            </p>
         </section>
         <section class="section" id="_geocoding_example">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a class="anchor" href="#_geocoding_example"></a>7.2.5.&nbsp;GeoCoding Example
                     </h3>
                  </div>
               </div>
            </div>
            <p>Example for reverse geocoding and determining the route from one to another location.</p><pre class="programlisting highlight"><code data-lang="cypher">WITH
        "21 rue Paul Bellamy 44000 NANTES FRANCE" AS fromAddr,
        "125 rue du docteur guichard 49000 ANGERS FRANCE" AS toAddr

call apoc.load.json("http://www.yournavigation.org/transport.php?url=http://nominatim.openstreetmap.org/search&amp;format=json&amp;q=" + replace(fromAddr, ' ', '%20')) YIELD value AS from

WITH from, toAddr  LIMIT 1

call apoc.load.json("http://www.yournavigation.org/transport.php?url=http://nominatim.openstreetmap.org/search&amp;format=json&amp;q=" + replace(toAddr, ' ', '%20')) YIELD value AS to

CALL apoc.load.json("https://router.project-osrm.org/viaroute?instructions=true&amp;alt=true&amp;z=17&amp;loc=" + from.lat + "," + from.lon + "&amp;loc=" + to.lat + "," + to.lon ) YIELD value AS doc

UNWIND doc.route_instructions as instruction

RETURN instruction</code></pre></section>
      </section>
      <footer><script type="text/javascript">
          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
          //Allow Linker
          ga('create', 'UA-1192232-34','auto', {'allowLinker': true});
          ga('send', 'pageview');
          // Load the plugin.
          ga('require', 'linker');
          // Define which domains to autoLink.
          ga('linker:autoLink', ['neo4j.org','neo4j.com','neotechnology.com','graphdatabases.com','graphconnect.com']);
        </script><script type="text/javascript">
          document.write(unescape("%3Cscript src='//munchkin.marketo.net/munchkin.js' type='text/javascript'%3E%3C/script%3E"));
        </script><script>Munchkin.init('773-GON-065');</script></footer>
   </body>
</html>